package code.main.core.net
{
	import code.main.AppData;
	import code.structure.manager.sound.MySoundManager;
	import code.tools.sound.src.SoundName;
	import code.untils.GameConst;
	import code.untils.LogConst;
	import code.untils.NetConst;
	import code.untils.SystemFunction;
	
	import com.patience.net.events.NetErrorEvent;
	
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import flash.utils.getTimer;
	
	
	/**
	 * 队列形式的后台交互类管理
	 * @author Yuri
	 *
	 */
	public class NetManager
	{
		private static var _instance:NetManager;
		
		/** 命令队列 */
		private var _queueList:Array;
		/** 计时器 */
		private var _timer:Timer;
		
		/** 后台交互 */
		private var _net:YNet;
		private var _isConnectNet:Boolean = true;
		
		/** 备份当前正在进行的后台请求信息 */
		private var _backupCurrentQuereList:Array;
		
		/** 延时发送计时器 （为了重复发包）*/
		private var _delayTimer:Timer;
		
		/** 包ID 唯一 */
		private var _iPackageId:int;
		
		/** 发包计时 */
		private var _iCmdTime:int;
		/** 叠加包 */
		private var _stackList:Array;
		//新手引导时过滤的方法
		private var _filterFun:Array = [NetConst.FUN_EXTENDS_INIT,NetConst.FUN_SAVE_NEWBIE_STEP, NetConst.FUN_INIT, NetConst.FUN_STATIC, NetConst.FUN_PROLOG, NetConst.FUN_GETTOKEN, NetConst.FUN_FRIEND_INFO];
		/**
		 *  首次baseinit requestid
		 */
		public static var FIRST_BASEINIT_REQUEST_ID:Number = 1;
		/**
		 *是否已经初始化第一次baseinit 
		 */
		public static var IS_REQUEST_FIRST_BASE_INIT:Boolean = false;
		public function NetManager()
		{
			init();
		}
		
		public static function getInstance():NetManager
		{
			if (!_instance) _instance = new NetManager();
			return _instance;
		}
		
		private function init():void
		{
			_timer = new Timer(GameConst.NET_INTERVAL_TIME);
			
			_delayTimer = new Timer(GameConst.NET_DELAY_INTERVAL_TIME, GameConst.NET_DELAY_COUNT + 1);
			
			_net = YNet.getIntance();
			_net.requestURL = AppData.gateUrl;
			_net.setCallBackFuns(callBackSucessedFun, callBackFailFun);
			
			_timer.addEventListener(TimerEvent.TIMER, onTimerHandler);
			_delayTimer.addEventListener(TimerEvent.TIMER, onDelayTimerHandler);
			
			_queueList = [];
			_stackList = [];
			_backupCurrentQuereList = [];
		}
		
		/**
		 *正常倒计时
		 * @param event
		 *
		 */
		private function onTimerHandler(event:TimerEvent):void
		{
			_iCmdTime++;
//			trace("正常倒计时 -------------->", _iCmdTime);
			if (_iCmdTime == GameConst.NET_SEND_INTERVAL_COUNT)
			{
				executeSendNetCmd(0, 0);
				_iCmdTime = 0;
			}
		}
		
		/**
		 *请求后台
		 * @param command 是否单包
		 * @param advance 提前时间
		 */
		private function executeSendNetCmd(command:int = 0, advance:int = 0):void
		{
			if (_backupCurrentQuereList.length > 0)
			{ //先执行还在链接中的
				execute();
				return;
			}
			if (_stackList.length == 0 && _queueList.length == 0) return;
			
			var requestObj:Object = { };
			
			if (_stackList.length > 0) {
				command = 1;
				_backupCurrentQuereList = _stackList.shift();
			} else {
				_backupCurrentQuereList = _queueList.concat();
				_queueList.length = 0;
			}
				
			
			requestObj.command = command;
			
			//添加唯一发送包ID
			_iPackageId = SystemFunction.packId;
			if(IS_REQUEST_FIRST_BASE_INIT){
				FIRST_BASEINIT_REQUEST_ID = _iPackageId;
			}
			requestObj.requestid = _iPackageId;
			requestObj.advanceTime = advance;
			requestObj.actionTime = SystemFunction.serverTime /*int(Number(SystemFunction.currentTime) * 0.001)*/;
			_backupCurrentQuereList.unshift(requestObj);
		/*	var obj:Object = _backupCurrentQuereList[1];
			requestObj.cmd = obj.request[0]+"."+obj.request[1];*/
			execute();
		}
		
		/**
		 *正常执行操作
		 *
		 */
		private function execute():void
		{
			if (!_isConnectNet) return;
			var obj:Object = _backupCurrentQuereList[0];
			obj.serverTime = SystemFunction.serverTime/* int(Number(SystemFunction.currentTime) * 0.001)*/;
			_net.send("", _backupCurrentQuereList);
			_delayTimer.reset();
			_delayTimer.start();
			_timer.stop();
			_iCmdTime = 0;
		}
		
		/**
		 *延迟重复发送
		 * @param event
		 *
		 */
		protected function onDelayTimerHandler(event:TimerEvent):void
		{
			if (!_isConnectNet)
			{
				_delayTimer.reset();
				return;
			}
			trace("延迟重复发送============>", _delayTimer.currentCount);
			if (_delayTimer.currentCount == _delayTimer.repeatCount)
			{ 
				trace("多次延迟发送还是无法成功！！！！！！！！！！！");
				_isConnectNet = false;
				_delayTimer.reset();
				_timer.reset();
				MySoundManager.playSound(SoundName.ERROR);
				var nErrorE:NetErrorEvent = new NetErrorEvent(NetErrorEvent.EVENT_NET_ERROR, LogConst.ERRPOP_NETWORKTIMEOUT_CODE);
				nErrorE.errorCode = LogConst.ERRPOP_NETWORKTIMEOUT_CODE + "";
				_net.dispatchEvent(nErrorE);
				return;
			}
			var obj:Object = _backupCurrentQuereList[0];
			obj.serverTime =  SystemFunction.serverTime/*int(Number(SystemFunction.currentTime) * 0.001)*/;
			_net.send("", _backupCurrentQuereList);
		}
		
		/**
		 * 增加命令
		 * @param cmd 命令
		 * @param isNeedCallBack
		 *
		 */
		public function addNetCmd(arr:Array, isNeedCallBack:Boolean = false):void
		{
			//trace("addNetCmd::",arr);
			var cmd:Object = {};
			cmd.id = SystemFunction.cmdId;
			cmd.timer = GameConst.NET_SEND_INTERVAL_COUNT - _iCmdTime;
			cmd.excutetime = SystemFunction.serverTime;
			cmd.request = arr;
			
			_queueList.push(cmd);
			if (isNeedCallBack)
			{
				if (_backupCurrentQuereList.length > 0) {
					arr = _queueList.concat();
					_stackList.push(arr);
					_queueList.length = 0;
					return;
				}
				executeNow();
				return;
			}
			
			if (!_timer.running && _isConnectNet)
				_timer.start();
		}
		
		/**
		 * 详细增加命令，在这里进行封装然后调用上述方法
		 * @param cmdPath
		 * @param funName
		 * @param parms
		 * @param isNeedCallBack
		 *
		 */
		public function addNetCmdDetail(cmdPath:String, funName:String, parms:Array, isNeedCallBack:Boolean = false):void
		{
			if (AppData.isNew && _filterFun.indexOf(funName) == -1) return;
			addNetCmd([cmdPath, funName, parms], isNeedCallBack);
		}
		
		/**
		 *立即执行
		 */
		public function executeNow():void
		{
			if (_timer.running) _timer.stop();
			executeSendNetCmd(1, GameConst.NET_SEND_INTERVAL_COUNT - _iCmdTime);
			_timer.reset();
			_iCmdTime = 0;
		}
		
		/**
		 *返回成功函数
		 * requestObj  {"requestid":packid,"command":1}
		 */
		private function callBackSucessedFun(requestObj:Object):void
		{
			if (int(requestObj.requestid) != _iPackageId)
				return;
			
			_delayTimer.reset();
			_backupCurrentQuereList.length = 0;
			if (_stackList.length > 0 || _queueList.length > 0)
				executeSendNetCmd(0, 0);
		}
		
		/**
		 * 返回失败函数
		 * @param errorCode 错误标示
		 *
		 */
		private function callBackFailFun(errorCode:int):void
		{
			_isConnectNet = false;
			_delayTimer.reset();
			_backupCurrentQuereList.length = 0;
			_timer.stop();
			switch (errorCode)
			{
			
			}
			MySoundManager.playSound(SoundName.ERROR);
		}
		
		public function get net():YNet
		{ return _net; }
		
		public function set net(value:YNet):void
		{ _net = value; }

		/** *是否在连接 */
		public function get isConnectNet():Boolean
		{
			return _isConnectNet;
		}

		/**
		 * @private
		 */
		public function set isConnectNet(value:Boolean):void
		{
			_isConnectNet = value;
		}

	
	}
}